#ifdef WIN32
#include <windows.h>
#include "windirent.h"
#define _snprintf snprintf
#endif

#ifdef LINUX
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>

#endif

#include "Disktools.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

bool isdirendkey(char a)
{
    if((a == '\\') || (a == '/'))
    {
        return true;
    }
    return false;
    
}

bool checkdir(const char * dirs)  // ���Ŀ¼�Ƿ����
{
    DIR * pdir = opendir(dirs);
    if(pdir)
    {
        closedir(pdir);
        return true;
    }
    return false;
}

bool mkdironedir(const char * dirs)  // ��������Ŀ¼
{
    if(!dirs || (strlen(dirs) == 0))
    {
        return false;
    }
    std::string url = "";
    url = dirs;
    if(!isdirendkey(dirs[strlen(dirs) - 1]))
    {
        url += "/";
    }

    if(checkdir(url.c_str()))
    {
        //printf(" checkdir %s success \n",url.c_str() );
        return true;
    }
    else
    {
        //printf(" checkdir %s fail \n",url.c_str() );
    }
#ifdef LINUX
    
    if(0 == mkdir(url.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH))
    {
        //printf("mkdir %s success\n", url.c_str());
        return true;
    }
    else
    {
        //printf("mkdir %s false\n", url.c_str());
        return false;
    }
#endif
    
#ifdef WIN32
    
    if ( true == CreateDirectory( url.c_str(), NULL ) )
    {   
        return true;
    }
    else
    {   
        return false;
    }

#endif
    
}

bool mkdirs(const char *dirs) // ����Ŀ¼ ���Խ������Ŀ¼
{
    char buff[2046] = { 0 };
    
    //snprintf(buff, sizeof(buff) -1 ,"%s", dirs);
    sprintf(buff, "%s", dirs);
    //printf("mkdirs %s \n", dirs);
    for(int i = 0; i < strlen(dirs); ++i)
    {
        if(isdirendkey(dirs[i]))
        {
            char tmpbuff[2046] = { 0 };
            //snprintf(tmpbuff, sizeof(buff) -1,"%s", dirs);
            sprintf(tmpbuff, "%s", dirs);
            tmpbuff[i + 1] = 0;
            //printf("mkdir onedir %s \n", tmpbuff);
            
            if(!mkdironedir(tmpbuff))
            {
                return false;
            }
        }
    }
    
    return true;
    
}

bool copyfile(const char * src, const char * dest)  // ��src copy �� Ŀ��Ŀ¼
{
    // ����2��Ŀ¼
    {
        //printf("%s << %s \n", src, dest);
        char buffsrc[2046] = { 0 };
        char buffdes[2046] = { 0 };
        
        //snprintf(buffsrc, 2046 -1, "%s", src);
        //snprintf(buffdes, 2046 -1, "%s", dest);
        
        sprintf(buffsrc, "%s", src);
        sprintf(buffdes, "%s", dest);
        
        for(int i = 2046 - 1; i >= 0; --i)
        {
            if(isdirendkey(buffsrc[i]))
            {
                for(int k = i + 1; k < 2046 - 1; ++k)
                {
                    buffsrc[k] = 0;
                }
                break;
            }
            
        }

        for(int i = 2046 - 1; i >= 0; --i)
        {
            if(isdirendkey(buffdes[i]))
            {
                for(int k = i + 1; k < 2046 - 1; ++k)
                {
                    buffdes[k] = 0;
                }
                break;
            }
        }
        //printf("src %s  \n", buffsrc);
        //printf("des %s   \n",   buffdes);
        
        mkdirs(buffsrc);
        mkdirs(buffdes);
        
    }
    //
    
    // copy �ļ�
    FILE *FPSRC = 0;
    FILE *FPDEST = 0;
    
    FPSRC = fopen(src, "rb");
    FPDEST = fopen(dest, "wb");
    
    if(!(FPSRC && FPDEST))
    {
        if(FPSRC)
        {
            fclose(FPSRC);
            FPSRC = 0;
        }
        if(FPDEST)
        {
            fclose(FPDEST);
        }
        return false;
    }
    char buff[1024] = { 0 };
    fseek(FPSRC, 0, 0);
    fseek(FPDEST, 0, 0);
    
    while(1)
    {
        int len = fread(buff, 1, 1024, FPSRC);
        
        if(len > 0)
        {
            fwrite(buff, 1, len, FPDEST);
        }
        else
        {
            break;
        }
    }

    fclose(FPSRC);
    fclose(FPDEST);
    return true;
    
}
//���ļ���ֿ�
bool GetfileNmae(const char * src, std::string &filename,
        std::string &appfilename)
{
    std::string name = src;
    std::string::size_type pos;
    
    if((pos = name.find(".")) != std::string::npos)
    {
        filename = name.substr(0, pos);
        appfilename = name.substr(pos + 1);
        return true;
    }
    return false;
}

//��ȡĳ��Ŀ¼�������е��ļ�����
bool GetAllFile(const char * dirs, std::list<std::string> &filelist)
{
    std::string url = dirs;
    if(!url.size())
    {
        return true;
    }
    if(!isdirendkey(url[strlen(url.c_str()) - 1]))
    {
        url += "/";
    }

    DIR * pdir = opendir(url.c_str());
    if(!pdir)
    {
        return true;
    }
    dirent *ddir = NULL;
    while(ddir = readdir(pdir))
    {
        if(strcmp(ddir->d_name, ".") == 0)
        {
            continue;
        }

        if(strcmp(ddir->d_name, "..") == 0)
        {
            continue;
        }

        std::string files = url + ddir->d_name;
        if(!checkdir(files.c_str()))
        {
            //printf("%s \n", ddir->d_name);
            
            std::string fl = ddir->d_name;
            filelist.push_back(fl);
        }
        
    }

    closedir(pdir);
    
    return true;
}

int DiskStricmp(const char * a, const char * b) // һ���0
{
    if(strlen(a) != strlen(b))
    {
        return 1;
    }

    while(*a)
    {
        if(tolower(*a) != tolower(*b))
        {
            return 1;
        }

        a++;
        b++;
        
    }
    
    return 0;
    
}

void GetDirFiles(std::string dir, std::vector<std::string> &lists)
{
#ifdef WIN32
    
    char endkey = '\\';
#else
    
    char endkey = '/';
#endif
    
    if(!dir.length())
    {
        return;
    }

    if(dir[dir.length() - 1] != endkey)
    {
        
        dir.push_back(endkey);
    }

    DIR * pdir = opendir(dir.c_str());
    if(pdir)
    {
        while(1)
        {
            dirent *pdirent = readdir(pdir);
            
            if(pdirent)
            {
                std::string filename = "";
                std::string files = pdirent->d_name;
                filename = dir + pdirent->d_name;
                const std::string s1 = ".", s2 = "..";
                if((s1 == files) || (s2 == files))
                {
                    continue;
                }
                if(opendir(filename.c_str()) == NULL)
                {
                    lists.push_back(filename);
                    //printf("%s\n", filename.c_str());
                    
                }
                else
                {
                    GetDirFiles(filename, lists);
                }
                
            }
            else
            {
                break;
                
            }
            
        }
        closedir(pdir);
        
    }
}

void CopyfileToGether(std::string dest, std::vector<std::string> filelist)
{
    
    FILE *FPSRC = 0;
    FILE *FPDEST = 0;
    const int bufflen = 1024 * 10;
    FPDEST = fopen(dest.c_str(), "wb");
    char buff[bufflen] = { 0 };
    for(std::vector<std::string>::iterator pos = filelist.begin();
            pos != filelist.end(); ++pos)
            {
        FPSRC = fopen((*pos).c_str(), "rb");
        
        while(1)
        {
            int len = 0;
            len = fread(buff, 1, bufflen, FPSRC);
            
            if(len > 0)
            {
                int needsend = len;
                int sended = 0;
                while(1)
                {
                    int thistime = fwrite(buff + sended, 1, needsend, FPDEST);
                    if(thistime > 0)
                    {
                        sended += thistime;
                        needsend -= thistime;
                        
                        if(needsend <= 0)
                        {
                            break;
                        }
                        
                    }
                    else
                    {
                        break;
                    }
                }
                
            }
            else
            {
                break;
            }
            
        }
        fclose(FPSRC);
        FPSRC = 0;
        
    }

    fclose(FPDEST);
    FPDEST = 0;
    
}
